home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / hsc / source / ugly / ustring.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-02  |  8.5 KB  |  419 lines

  1. /*
  2.  * This source code is part of hsc, a html-preprocessor,
  3.  * Copyright (C) 1993-1997  Thomas Aglassinger
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. /*
  21.  * ugly/ustring.c - ugly string functions
  22.  *
  23.  * updated: 11-May-1997
  24.  * created: 31-Jul-1993
  25.  */
  26.  
  27. #include <ctype.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31.  
  32. #include "utypes.h"
  33. #include "umemory.h"
  34.  
  35. #define NOEXTERN_UGLY_USTRING_H
  36. #include "ustring.h"
  37.  
  38. /*
  39.  * last_ch
  40.  *
  41.  * return last char of a string, or 0 on empty string
  42.  */
  43. int last_ch(STRPTR s)
  44. {
  45.     size_t len = strlen(s);
  46.     int ch = 0;
  47.  
  48.     if (len)
  49.     {
  50.         ch = s[len - 1];
  51.     }
  52.     else
  53.     {
  54.         ch = 0;
  55.     }
  56.  
  57.     return ch;
  58. }
  59.  
  60. /*
  61.  * strclone
  62.  *
  63.  * create a clone of a string
  64.  *     (copy of string using its own memory area)
  65.  *
  66.  * params: *oldstr...ptr to string to clone
  67.  * result: ptr to copy of string;
  68.  * errors: out of memory: returns NULL
  69.  *
  70.  */
  71. STRPTR ugly_strclone(CONSTRPTR oldstr, STRPTR file, ULONG line)
  72. {
  73.     STRPTR newstr = NULL;
  74.  
  75.     if (oldstr)
  76.     {
  77.  
  78.         /* alloc mem for clone */
  79. #if DEBUG_UGLY_MEMORY
  80.         newstr = ugly_malloc_tracking(strlen(oldstr) + 1, file, line);
  81. #else
  82.         newstr = umalloc(strlen(oldstr) + 1);
  83. #endif
  84.  
  85.         if (newstr)             /* alloc sucessful? */
  86.             strcpy(newstr, oldstr);     /* Y-> copy data */
  87.  
  88.     }
  89.     return (newstr);            /* return result */
  90. }
  91.  
  92. /*
  93.  * upstr: convert a string to upper case
  94.  *
  95.  * params: *s...string to convert
  96.  *
  97.  */
  98. STRPTR upstr(STRPTR s)
  99. {
  100.     STRPTR s_old = s;
  101.  
  102.     if (s)
  103.         for (; *s != '\0'; s++)
  104.             *s = toupper(*s);
  105.  
  106.     return s_old;
  107. }
  108.  
  109. /*
  110.  * upstrcmp
  111.  *
  112.  * string compare, ignore case
  113.  *
  114.  * params: *s1, *s2...ptr to strings to compare
  115.  * result: -1: s1 < s2
  116.  *          0: s1 = s2
  117.  *          1: s1 > s2
  118.  *
  119.  */
  120. int upstrcmp(CONSTRPTR s1, CONSTRPTR s2)
  121. {
  122. #define QUICKY 1
  123. #if !QUICKY
  124.     int equal;                  /* result of _strcp() */
  125. #endif
  126.     unsigned char c1, c2;       /* chars currently comparing */
  127.     size_t i = 0;               /* string index counter */
  128.  
  129.     do
  130.     {
  131.         c1 = toupper(s1[i]);
  132.         c2 = toupper(s2[i]);
  133.         i++;
  134.     }
  135.     while (c1 && c2 && (c1 == c2));
  136.  
  137. #if QUICKY
  138.     return (c2 - c1);
  139. #else
  140.     if (c1 < c2)
  141.         equal = -1;             /* s1 < s2 */
  142.     else if (c1 > c2)
  143.         equal = +1;             /* s1 > s2 */
  144.     else
  145.         equal = 0;              /* s1 = s2 */
  146.  
  147.     return (equal);             /* return result */
  148. #endif
  149. }
  150.  
  151. /*
  152.  * upstrncmp
  153.  *
  154.  * string compare, ignore case, max. n chars
  155.  *
  156.  * params: *s1, *s2...ptr to strings to compare
  157.  *         n..........max. nr. of chars to compare
  158.  * result: -1: s1 < s2
  159.  *          0: s1 = s2
  160.  *          1: s1 > s2
  161.  *
  162.  */
  163. int upstrncmp(CONSTRPTR s1, CONSTRPTR s2, size_t n)
  164. {
  165.     int equal;                  /* result of _strcp() */
  166.     unsigned char c1, c2;       /* char of string currently comparing */
  167.     size_t i = 0;               /* string index counter */
  168.  
  169.     do
  170.     {
  171.         c1 = toupper(s1[i]);
  172.         c2 = toupper(s2[i]);
  173.         i++;
  174.     }
  175.     while (c1 && c2 && (c1 == c2) && (i < n));
  176.  
  177.     if (c1 < c2)
  178.         equal = -1;             /* s1 < s2 */
  179.     else if (c1 > c2)
  180.         equal = +1;             /* s1 > s2 */
  181.     else
  182.         equal = 0;              /* s1 = s2 */
  183.  
  184.     return (equal);             /* return result */
  185. }
  186.  
  187. /*
  188.  * upstrstr
  189.  *
  190.  * find a sub-string (case insensitive)
  191.  *
  192.  */
  193. STRPTR upstrstr(CONSTRPTR s1, CONSTRPTR s2)
  194. {
  195.     const char *c1;
  196.     const char *c2;
  197.  
  198.     do
  199.     {
  200.         c1 = s1;
  201.         c2 = s2;
  202.  
  203.         while (*c1 != '\0' && (toupper(c1[0]) == toupper(c2[0])))
  204.         {
  205.             c1++;
  206.             c2++;
  207.         }
  208.  
  209.         if (*c2 == '\0')
  210.         {
  211.             return (char *) s1;
  212.         }
  213.     }
  214.     while (*s1++ != '\0');
  215.  
  216.     return NULL;
  217. }
  218.  
  219. /*
  220.  * freestr
  221.  *
  222.  * free memory used by a string
  223.  *
  224.  * params: s..string to free
  225.  *
  226.  * NOTE: strings created with strclone() or reallocstr
  227.  *       should be freed with this function instead of
  228.  *       ufree(). this will avoid problems when using
  229.  *       the memory-tracking feature of ugly.o
  230.  */
  231. void ugly_freestr(STRPTR s, STRPTR file, ULONG line)
  232. {
  233. #if DEBUG_UGLY_MEMORY
  234.     ugly_free(s, file, line);
  235. #else
  236.     ufree(s);
  237. #endif
  238. }
  239.  
  240. /*
  241.  * reallocstr
  242.  *
  243.  * free memory used by string, clone new data
  244.  *
  245.  * params:oldstr...prt to ptr of old string
  246.  *          *newstr...ptr to new string data
  247.  * errors: out of mem: returns NULL (old data are lost)
  248.  *
  249.  * IMPORTANT: old string has to be initialies like "oldstr = NULL;" before !!
  250.  *            first call like "reallocstr( &oldstr, "<new data>" );"
  251.  */
  252. void ugly_reallocstr(STRPTR * oldstr, CONSTRPTR newstr, STRPTR file, ULONG line)
  253. {
  254. #if DEBUG_UGLY_MEMORY
  255.     ugly_freestr(*oldstr, file, line);  /* free old string */
  256.     *oldstr = ugly_strclone(newstr, file, line);        /* clone new string */
  257. #else
  258.     ufree(*oldstr);             /* free old string */
  259.     *oldstr = strclone(newstr); /* clone new string */
  260. #endif
  261. }
  262.  
  263. /*
  264.  * ch2str
  265.  *
  266.  * convert single char to zero terminated string
  267.  *
  268.  * params: ch...char to convert
  269.  * result: ptr to internal buffer, where a string containning
  270.  *         "<ch>\0" is located.
  271.  *
  272.  * USAGE : buffer is rewritten at next call of _chstr(), so
  273.  *         be sure to clone string if you need it for a longer
  274.  *         time.
  275.  *         _ch2str() is mostly designed for parameter conversion
  276.  *         on string funtions, e.g s = strclone( ch2str( 'x' ) );
  277.  *
  278.  */
  279. STRPTR ch2str(const char ch)
  280. {
  281.     static char ch2str_buffer[2];       /* internal buffer */
  282.  
  283.     ch2str_buffer[0] = ch;
  284.     ch2str_buffer[1] = '\0';
  285.  
  286.     return ch2str_buffer;
  287. }
  288.  
  289. /*
  290.  * ustrrpbrk
  291.  *
  292.  * searches for last occurence of a char of _set in _str
  293.  *
  294.  * params: str...string to examine
  295.  *         set...chars to search for
  296.  * result: ptr where char of _set occured in _str
  297.  *         or NULL if none occurence found
  298.  *
  299.  * NOTE:   this is a clone of none-ansi-c function _strrpbrk()
  300.  *
  301.  */
  302. STRPTR ustrrpbrk(CONSTRPTR str, CONSTRPTR set)
  303. {
  304.     size_t i;
  305.     STRPTR result = NULL;
  306.  
  307.     if (str)
  308.     {
  309.  
  310.         i = strlen(str) - 1;
  311.  
  312.         while ((i) && (strchr(set, str[i]) == NULL))
  313.             i--;
  314.  
  315.         if (strchr(set, str[i]))
  316.             result = (STRPTR) & (str[i]);
  317.     }
  318.     return result;
  319.  
  320. }
  321.  
  322. /*
  323.  * str2long
  324.  *
  325.  * convert string expression to long value
  326.  *
  327.  * params: s....string to convert
  328.  *         num..ptr to destination long var
  329.  * result: TRUE, if sucessful
  330.  * errors: returen FALSE
  331.  *
  332.  */
  333. BOOL str2long(STRPTR s, LONG * num)
  334. {
  335.     BOOL conv_ok = FALSE;
  336.  
  337.     if (sscanf(s, "%d", (int *) num))
  338.     {
  339.         conv_ok = TRUE;
  340.     }
  341.     return conv_ok;
  342. }
  343.  
  344. /*
  345.  * long2str
  346.  *
  347.  * convert long value to string expresion
  348.  *
  349.  * params: num...value to convert
  350.  * result: ptr to converted string
  351.  * errors: returns NULL
  352.  *
  353.  */
  354. STRPTR long2str(LONG num)
  355. {
  356.     static char num2str_buffer[10];     /* internal buffer */
  357.  
  358.     STRPTR result_str = NULL;
  359.  
  360.     if (sprintf(num2str_buffer, "%d", (int) num))
  361.     {
  362.         result_str = num2str_buffer;
  363.     }
  364.     return result_str;
  365. }
  366.  
  367. /*
  368.  * strenum
  369.  *
  370.  * find a substring in an enumerator string
  371.  *
  372.  * params: str...substring to search for
  373.  *         set...set of legal substrings
  374.  *         sep...substring separator (eg "|")
  375.  * result:  0..not found
  376.  *         >0..index of substring found
  377.  *         <0..out of mem
  378.  * errors: out of mem: returns -1
  379.  *
  380.  * example: enumstr( "sepp", "hugo|sepp|resi", '|', STEN_CASE ) -> 2
  381.  *
  382.  * NOTE: calls strtok()
  383.  */
  384. LONG strenum(STRPTR str, STRPTR set, char sep, BYTE options)
  385. {
  386.     STRPTR s = strclone(set);
  387.     LONG found = 0;
  388.  
  389.     if (s)
  390.     {
  391.  
  392.         STRPTR nxtstr = strtok(s, ch2str(sep));
  393.         LONG count = 1;
  394.  
  395.         while (!found && nxtstr)
  396.         {
  397.  
  398.             if (options & STEN_NOCASE)
  399.             {
  400.                 if (!upstrcmp(str, nxtstr))
  401.                     found = count;
  402.             }
  403.             else if (!strcmp(str, nxtstr))
  404.                 found = count;
  405.  
  406.             count++;
  407.             nxtstr = strtok(NULL, ch2str(sep));
  408.  
  409.         }
  410.  
  411.         ufreestr(s);
  412.  
  413.     }
  414.     else
  415.         found = -1;
  416.  
  417.     return (found);
  418. }
  419.